#include "../include/TcpServer.h"
#include <stdio.h>

TcpServer::TcpServer(int port)
    : _port(port),
      _next_id(0),
      _enable_inactive_release(false),
      _acceptor(&_baseloop, port),
      _pool(&_baseloop)
{
    // 设置客服端的连接到来就执行的回调函数
    _acceptor.SetAcceptCallback(std::bind(&TcpServer::NewConnection, this, std::placeholders::_1));
    // 监听这个套接字
    _acceptor.Listen();
}

void TcpServer::NewConnection(int fd)
{
    _next_id++;
    PtrConnection conn(new Connection(_pool.NextLoop(), _next_id, fd));
    conn->SetMessageCallback(_message_callback);
    conn->SetClosedCallback(_closed_callback);
    conn->SetSvrClosedCallback(std::bind(&TcpServer::RemoveConnection, this, std::placeholders::_1));
    conn->SetConnectedCallback(_connected_callback);
    conn->SetAnyEventCallback(_event_callback);
    if (_enable_inactive_release)
        conn->EnableInactiveRelease(_timeout);
    conn->Established(); // 就绪初始化
    _conns.insert(std::make_pair(_next_id, conn));
}

void TcpServer::RemoveConnectionInLoop(const PtrConnection &conn)
{
    int id = conn->Id();
    auto it = _conns.find(id);
    if (it != _conns.end())
    {
        _conns.erase(it);
    }
}

void TcpServer::RemoveConnection(const PtrConnection &conn)
{
    _baseloop.RunInLoop(std::bind(&TcpServer::RemoveConnectionInLoop, this, conn));
}

void TcpServer::RunAfterInLoop(const Functor &task, int delay)
{
    _next_id++;
    _baseloop.TimerAdd(_next_id, delay, task);
}

void TcpServer::SetThreadCount(int count)
{
    return _pool.SetThreadCount(count);
}

void TcpServer::SetConnectedCallback(const ConnectedCallback &cb)
{
    _connected_callback = cb;
}

void TcpServer::SetMessageCallback(const MessageCallback &cb)
{
    _message_callback = cb;
}

void TcpServer::SetClosedCallback(const ClosedCallback &cb)
{
    _closed_callback = cb;
}
void TcpServer::SetAnyEventCallback(const AnyEventCallback &cb)
{
    _event_callback = cb;
}

void TcpServer::EnableInactiveRelease(int timeout)
{
    _timeout = timeout;
    _enable_inactive_release = true;
}

void TcpServer::RunAter(const Functor &task, int delay)
{
    _baseloop.RunInLoop(std::bind(&TcpServer::RunAfterInLoop, this, task, delay));
}

void TcpServer::Start()
{
    _pool.Create();
    _baseloop.Start();
}